import {
  LeftOutlined,
  RightOutlined,
  VerticalAlignBottomOutlined,
  VerticalAlignTopOutlined,
  VerticalLeftOutlined,
  VerticalRightOutlined
} from "@ant-design/icons"
import { useModel } from "@umijs/max"
import { App, Button, Card, Col, Form, InputNumber, Modal, Row } from "antd"
import React, { useEffect, useState } from "react"
import { Image, Layer, Stage } from "react-konva"
import CameraParamsForm from "./CameraParamsForm"
import ImageJointParams from "./ImageJointParamsForm"

// 图像组件
const LineCameraJointImage: React.FC<{ imageData: string | null }> = ({ imageData }) => {
  const [image, setImage] = useState<HTMLImageElement | null>(null)

  useEffect(() => {
    if (imageData) {
      const img = new window.Image()
      img.src = `data:image/jpeg;base64,${imageData}`
      img.onload = () => {
        setImage(img)
      }
    } else {
      setImage(null)
    }
  }, [imageData])

  return <Image image={image} width={450} height={450} />
}

const CountBoardSizeImage: React.FC<{ imageData: string | null }> = ({ imageData }) => {
  const [image, setImage] = useState<HTMLImageElement | null>(null)

  useEffect(() => {
    if (imageData) {
      const img = new window.Image()
      img.src = `data:image/jpeg;base64,${imageData}`
      img.onload = () => {
        setImage(img)
      }
    } else {
      setImage(null)
    }
  }, [imageData])

  return <Image image={image} width={800} height={800} />
}

const CheckSizeImage: React.FC<{ imageData: string | null }> = ({ imageData }) => {
  const [image, setImage] = useState<HTMLImageElement | null>(null)

  useEffect(() => {
    if (imageData) {
      const img = new window.Image()
      img.src = `data:image/jpeg;base64,${imageData}`
      img.onload = () => {
        setImage(img)
      }
    } else {
      setImage(null)
    }
  }, [imageData])

  return <Image image={image} width={800} height={850} />
}

const LineCameraJoint: React.FC = () => {
  const [form] = Form.useForm()
  const { message } = App.useApp()
  const { callPy } = useModel("websocketModel")

  // 状态管理
  const [movePix, setMovePix] = useState(0)
  const [inputWidth, setInputWidth] = useState(0)
  const [inputHeight, setInputHeight] = useState(0)
  const [jointImageData, setJointImageData] = useState<string | null>(null)
  const [checkImageData, setCheckImageData] = useState<string | null>(null)
  const [showModal, setShowModal] = useState(false)
  const { cutPlcState } = useModel("deviceModel")
  const [inputSize, setInputSize] = useState([0, 0])
  const [boardSize, setBoardSize] = useState([0, 0])
  const [showInfo, setShowInfo] = useState("")
  const [countImageData, setCountImageData] = useState<string | null>(null)
  const [checkModal, setCheckModal] = useState(false)
  const [checkSize, setCheckSize] = useState([0, 0])
  const [checkError, setCheckError] = useState([0, 0])
  const [checkInfo, setCheckInfo] = useState("")

  const calcMmToPix = async () => {
    setShowModal(false)
    setCountImageData(null)
    const response = await callPy("cameraTool", "calc_mm_to_pix_from_web", [])
    if (response.state) {
      setShowModal(true)
      setCountImageData(response.data[0])
      setBoardSize(response.data[1])
      setInputSize(response.data[2])
      setShowInfo(response.data[3])
    } else {
      message.error("计算失败: " + response.info)
    }
  }

  const saveMmToPix = async () => {
    setShowModal(false)
    setCountImageData(null)
    const response = await callPy("cameraTool", "save_mm_to_pix_from_web", [])
    if (response.state) {
      message.success("保存成功")
    } else {
      message.error("保存失败: " + response.info)
    }
  }

  const openCountBoardSizeDir = async () => {
    const response = await callPy("cameraTool", "open_count_board_size_dir_from_web", [])
    if (response.state) {
      message.success("目录打开成功")
    } else {
      message.error("目录打开失败: " + response.info)
    }
  }

  const checkSizeOk = async () => {
    setCheckModal(false)
    setCheckImageData(null)
    const response = await callPy("cameraTool", "check_size_ok_from_web", [])
    if (response.state) {
      setCheckModal(true)
      setCheckImageData(response.data[0])
      setBoardSize(response.data[1])
      setInputSize(response.data[2])
      setShowInfo(response.data[3])
      setCheckError(response.data[4])
    } else {
      message.error("验证失败: " + response.info)
    }
  }

  const checkSizeError = async () => {
    setCheckModal(false)
    setCheckImageData(null)
    const response = await callPy("cameraTool", "check_size_error_from_web", [])
    if (response.state) {
      setCheckModal(true)
      setCheckImageData(response.data[0])
      setBoardSize(response.data[1])
      setInputSize(response.data[2])
      setShowInfo(response.data[3])
      setCheckError(response.data[4])
    } else {
      message.error("验证失败: " + response.info)
    }
  }

  const totalBoardIsError = async () => {
    setShowModal(false)
    setCountImageData(null)
    const response = await callPy("cameraTool", "total_board_is_error_from_web", [])
    if (response.state) {
      setShowModal(true)
      setCountImageData(response.data[0])
      setBoardSize(response.data[1])
      setInputSize(response.data[2])
      setShowInfo(response.data[3])
    } else {
      message.error("物料查找Error失败: " + response.info, 5)
    }
  }

  const totalBoardIsOk = async () => {
    setShowModal(false)
    setCountImageData(null)
    const response = await callPy("cameraTool", "total_board_is_ok_from_web", [])
    if (response.state) {
      setShowModal(true)
      setCountImageData(response.data[0])
      setInputSize(response.data[1])
      setBoardSize(response.data[2])
      setShowInfo(response.data[3])
    } else {
      message.error("物料查找失败: " + response.info)
    }
  }

  // 相机操作函数
  const start_cut_plc = async () => {
    const response = await callPy("cameraTool", "start_cut_plc_from_web", [])
    if (response.state) {
      message.success("分板机启动成功")
    } else {
      message.error("分板机启动失败: " + response.info)
    }
  }

  const stop_cut_plc = async () => {
    const response = await callPy("cameraTool", "stop_cut_plc_from_web", [])
    if (response.state) {
      message.success("分板机停止成功")
    } else {
      message.error("分板机停止失败: " + response.info)
    }
  }

  const reset_cut_plc = async () => {
    const response = await callPy("cameraTool", "reset_cut_plc_from_web", [])
    if (response.state) {
      message.success("分板机复位成功")
    } else {
      message.error("分板机复位失败: " + response.info)
    }
  }

  const closeCameraDoorAlarm = async () => {
    const response = await callPy("cameraTool", "close_camera_door_alarm_from_web", [])
    if (response.state) {
      message.success("屏蔽视觉门报警成功")
    } else {
      message.error("屏蔽视觉门报警失败: " + response.info)
    }
  }

  const getImageForImageJoint = async () => {
    setJointImageData(null)
    const response = await callPy("cameraTool", "get_image_for_joint_from_web", [])
    if (response.state && response.data) {
      setJointImageData(response.data)
    } else {
      message.error("获取图像失败: " + response.info)
    }
  }

  // 图像处理函数
  const moveToInnerLeft = async () => {
    const moveParams = [0, movePix, movePix, 0, 0]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  const moveToOutLeft = async () => {
    const moveParams = [0, -movePix, -movePix, 0, 0]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  // 尺寸计算函数
  const saveTotalBoardSize = async () => {
    const response = await callPy("cameraTool", "save_total_board_size_from_web", [
      inputWidth,
      inputHeight
    ])
    if (response.state) {
      message.success("保存成功")
    } else {
      message.error("保存失败: " + response.info)
    }
  }

  const reGetImageForImageJoint = async () => {
    setJointImageData(null)
    const response = await callPy("cameraTool", "re_get_image_for_joint_from_web", [])
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  const openImageJointDir = async () => {
    const response = await callPy("cameraTool", "open_image_joint_dir_from_web", [])
    if (response.state) {
      message.success("打开目录成功")
    } else {
      message.error("打开目录失败: " + response.info)
    }
  }

  const moveLeftMatter = async () => {
    const moveParams = [movePix, 0, 0, 0, 0, 0, 0, 0]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  const moveRightMatter = async () => {
    const moveParams = [0, 0, 0, 0, 0, movePix, 0, 0]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
    message.success("截掉右边型材成功")
  }

  const moveLeftUp = async () => {
    const moveParams = [0, 0, 0, 0, -movePix]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  const moveLeftDown = async () => {
    const moveParams = [0, 0, 0, 0, movePix]
    setJointImageData(null)
    const response = await callPy("cameraTool", "move_joint_image_from_web", moveParams)
    if (response.state && response.data) {
      setJointImageData(response.data)
    }
  }

  const getEightImageForCount = async () => {
    const response = await callPy("cameraTool", "get_eight_image_for_count", [])
    if (response.state && response.data) {
      setCountImageData(response.data)
    }
  }

  const countBoardSize = async () => {
    setShowModal(false)
    setCountImageData(null)
    const response = await callPy("cameraTool", "count_board_size_from_web", [])
    if (!response.state) {
      message.error("计算失败: " + response.info, 5)
    } else {
      setShowModal(true)
      setCountImageData(response.data[0])
      setBoardSize(response.data[1])
      setInputSize(response.data[2])
      setShowInfo(response.data[3])
    }
  }

  const checkMmToPix = async () => {
    setCheckModal(false)
    setCheckImageData(null)
    const response = await callPy("cameraTool", "check_mm_to_pix", [])
    if (response.state) {
      setCheckModal(true)
      setCheckImageData(response.data[0])
      setCheckSize(response.data[1])
      setInputSize(response.data[2])
      setCheckInfo(response.data[3])
      setCheckError(response.data[4])
    } else {
      message.error("验证失败: " + response.info, 5)
    }
  }

  return (
    <>
      <Card title={<span style={{ color: "#425273" }}>相机参数设置</span>}>
        <CameraParamsForm />
      </Card>

      <Card style={{ marginTop: 10 }}>
        <Card.Grid style={{ width: "52%", textAlign: "left" }}>
          <Stage width={550} height={550}>
            <Layer>
              {jointImageData ? (
                <LineCameraJointImage imageData={jointImageData} />
              ) : (
                <LineCameraJointImage imageData={null} />
              )}
            </Layer>
          </Stage>
        </Card.Grid>
        <Card.Grid style={{ width: "48%", textAlign: "left" }}>
          <Col>
            <Row>
              <span style={{ marginLeft: 15 }}>
                状态:&nbsp;&nbsp;&nbsp;{" "}
                {cutPlcState.isRs ? (
                  <span style={{ color: "#FF0000", fontSize: 16 }}>急停中</span>
                ) : cutPlcState.isRun ? (
                  <span style={{ color: "#00FF00", fontSize: 16 }}>运行中</span>
                ) : (
                  <span style={{ color: "#112233", fontSize: 16 }}>待机</span>
                )}
              </span>
              <Button
                type="primary"
                onClick={start_cut_plc}
                style={{ marginLeft: 15 }}
                disabled={cutPlcState.isRun || cutPlcState.isRs}
              >
                分板机启动
              </Button>
              <Button type="primary" onClick={stop_cut_plc} style={{ marginLeft: 15 }}>
                分板机停止
              </Button>
              <Button type="primary" onClick={reset_cut_plc} style={{ marginLeft: 15 }}>
                分板机复位
              </Button>
            </Row>
            <Row style={{ marginTop: 20 }}>
              <Button
                type="primary"
                onClick={getImageForImageJoint}
                style={{ marginLeft: 15 }}
              >
                抓取图片
              </Button>
              <Button
                type="primary"
                onClick={reGetImageForImageJoint}
                style={{ marginLeft: 15 }}
              >
                重新拍照
              </Button>
              <Button
                type="primary"
                onClick={openImageJointDir}
                style={{ marginLeft: 15 }}
              >
                查看拼接图片
              </Button>
            </Row>
            <Row style={{ marginTop: 20 }}>
              <ImageJointParams />
            </Row>
            <Row style={{ marginTop: 20, display: "flex", alignItems: "center" }}>
              <span style={{ marginLeft: 10, fontSize: 16 }}>
                移动的像素数(只能是整数)
              </span>
              <InputNumber
                onChange={(value) => setMovePix(value)}
                style={{ marginLeft: 10, width: 80 }}
                defaultValue={movePix}
              />
            </Row>
            <Row style={{ marginTop: 20 }}>
              <p>
                左边图像拼接移动的时候,左边和中间的图像会同时移动相同的像素数,上下移动的时候,中间图不变,移动左侧图像
              </p>
              <div>
                <Button type="primary" onClick={moveToInnerLeft}>
                  <VerticalLeftOutlined />
                  <VerticalRightOutlined />
                </Button>
                <Button type="primary" onClick={moveToOutLeft} style={{ marginLeft: 20 }}>
                  <LeftOutlined />
                  <RightOutlined />
                </Button>
                <Button type="primary" onClick={moveLeftUp} style={{ marginLeft: 20 }}>
                  <VerticalAlignTopOutlined />
                </Button>
                <Button type="primary" onClick={moveLeftDown} style={{ marginLeft: 20 }}>
                  <VerticalAlignBottomOutlined />
                </Button>
              </div>
            </Row>
            <Row style={{ marginTop: 20 }}>
              <div>
                <p>截取左右的型材,输入截掉的像素数进行截取,负数可以补回截掉的部分</p>
                <Button type="primary" onClick={moveLeftMatter}>
                  截掉左边型材
                </Button>
                <Button
                  type="primary"
                  onClick={moveRightMatter}
                  style={{ marginLeft: 20 }}
                >
                  截掉右边型材
                </Button>
              </div>
            </Row>

            <Row style={{ marginTop: 20 }}>
              <div>
                <p>
                  <span style={{ color: "#FF0000", fontSize: 13 }}>
                    像素比高宽比计算(图像拼接完成以后做这一步,先录入物料尺寸(mm))
                  </span>
                </p>
                <span>拍摄物料宽:</span>
                <InputNumber
                  onChange={(value) => setInputWidth(value)}
                  style={{ marginLeft: 10, width: 80 }}
                  defaultValue={inputWidth}
                />
                <span style={{ marginLeft: 10 }}>拍摄物料高:</span>
                <InputNumber
                  onChange={(value) => setInputHeight(value)}
                  style={{ marginLeft: 10, marginRight: 10, width: 80 }}
                  defaultValue={inputHeight}
                />
                <Button
                  type="primary"
                  style={{ marginLeft: 20 }}
                  onClick={saveTotalBoardSize}
                >
                  保存
                </Button>
              </div>
            </Row>
            <Row style={{ marginTop: 20 }}>
              <Button type="primary" onClick={getEightImageForCount}>
                拍8张图用于统计
              </Button>
            </Row>

            <Row style={{ marginTop: 20 }}>
              <Button type="primary" onClick={countBoardSize}>
                计算高宽比和像素比
              </Button>
              <Button type="primary" style={{ marginLeft: 20 }} onClick={checkMmToPix}>
                验证高宽比和像素比
              </Button>
            </Row>
          </Col>
        </Card.Grid>
      </Card>

      {showModal && (
        <Modal
          open={showModal}
          onCancel={() => setShowModal(false)}
          width="90vw"
          style={{ top: 10 }}
          footer={null}
          title="计算高宽比和像素比"
        >
          <Card style={{ width: "100%" }}>
            <Card.Grid style={{ width: "62%", textAlign: "left" }}>
              <Stage width={800} height={800}>
                <Layer>
                  <CountBoardSizeImage imageData={countImageData} />
                </Layer>
              </Stage>
            </Card.Grid>
            <Card.Grid style={{ width: "38%", textAlign: "left" }}>
              <Col>
                <Row>
                  <div>
                    <p>
                      <span style={{ color: "#FF0000", fontSize: 13 }}>
                        如果画的物料区域的框是对的就点击OK按钮,如果物料查找有偏差,就点击Error按钮
                      </span>
                    </p>
                    <p>
                      计算尺寸(pix): (宽,高) =({boardSize[0]},&nbsp;{boardSize[1]})
                    </p>
                    <p>
                      录入尺寸(mm): (宽,高) =({inputSize[0]},&nbsp;{inputSize[1]})
                    </p>
                    <Button type="primary" onClick={totalBoardIsOk}>
                      物料查找OK
                    </Button>
                    <Button
                      style={{ marginLeft: 20 }}
                      type="primary"
                      onClick={totalBoardIsError}
                    >
                      物料查找Error
                    </Button>
                  </div>
                </Row>
                <Row style={{ marginTop: 10 }}>
                  <div>
                    <Button type="primary" onClick={calcMmToPix}>
                      计算像素比
                    </Button>
                    <Button
                      style={{ marginLeft: 25 }}
                      type="primary"
                      onClick={saveMmToPix}
                    >
                      保存
                    </Button>
                    <Button
                      style={{ marginLeft: 20 }}
                      type="primary"
                      onClick={openCountBoardSizeDir}
                    >
                      查看图像目录
                    </Button>
                  </div>
                </Row>
                <Row style={{ marginTop: 20 }}>
                  <p style={{ marginTop: 20 }}>
                    <span style={{ color: "#FF0000" }}>提示消息:</span>
                    <span style={{ marginLeft: 10 }}>{showInfo}</span>
                  </p>
                </Row>
              </Col>
            </Card.Grid>
          </Card>
        </Modal>
      )}

      {checkModal && (
        <Modal
          title={"物料区域尺寸识别是否正确确认框"}
          width={window.screen.availWidth - 80}
          style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0 }}
          closable={false}
          footer={null}
        >
          <Card>
            <Card>
              <Card.Grid style={{ width: "62%", textAlign: "left" }}>
                <Stage width={800} height={850}>
                  <Layer>
                    <CheckSizeImage imageData={checkImageData} />{" "}
                  </Layer>
                </Stage>
              </Card.Grid>
              <Card.Grid style={{ width: "38%", textAlign: "left" }}>
                <Col>
                  <Row>
                    <p>
                      <span style={{ color: "#FF0000" }}>
                        如果画的物料区域的框是对的就点击OK按钮,如果物料查找有偏差,就点击Error按钮
                      </span>
                    </p>
                    <p>
                      计算尺寸(mm): (宽,高) =({checkSize[0]},&nbsp;{checkSize[1]})
                    </p>
                    <p>
                      录入尺寸(mm): (宽,高) =({inputSize[0]},&nbsp;{inputSize[1]})
                    </p>
                    <p>
                      识别误差(mm): (宽,高) = ({checkError[0]},&nbsp;{checkError[1]})
                    </p>
                    <Button type="primary" onClick={checkSizeOk}>
                      物料查找OK
                    </Button>
                    <Button
                      style={{ marginLeft: 20 }}
                      type="primary"
                      onClick={checkSizeError}
                    >
                      物料查找Error
                    </Button>
                    <Button
                      style={{ marginLeft: 20 }}
                      type="primary"
                      onClick={calcCheckError}
                    >
                      计算平均误差
                    </Button>
                    <Button
                      style={{ marginLeft: 10 }}
                      type="primary"
                      onClick={openCountBoardSizeDir}
                    >
                      查看图像目录
                    </Button>
                  </Row>
                  <Row style={{ marginTop: 20 }}>
                    <p style={{ marginTop: 20 }}>
                      <span style={{ color: "#FF0000" }}>提示消息:</span>
                      <span style={{ marginLeft: 10 }}>{checkInfo}</span>
                    </p>
                  </Row>
                </Col>
              </Card.Grid>
            </Card>
          </Card>
        </Modal>
      )}
    </>
  )
}

export default () => (
  <App>
    <LineCameraJoint />
  </App>
)
